package com.fivefu.core.hillstone.services.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fivefu.base.common.utils.str.StrUtils;
import com.fivefu.core.hillstone.constant.HillstoneRequestTypeEnum;
import com.fivefu.core.hillstone.dto.request.LoginDto;
import com.fivefu.core.hillstone.properties.HillstoneProperties;
import com.fivefu.core.hillstone.services.HillstoneService;
import com.fivefu.core.hillstone.utils.EncryptUtils;
import com.fivefu.core.hillstone.utils.OkHttpClients;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

@Service
public class HillstoneServiceImpl implements HillstoneService {

    private Logger logger = LoggerFactory.getLogger(HillstoneServiceImpl.class);

    private final static String baseurl = "http://192.168.4.224:8314"; //正式访问地址
    private static String username = "test1";
    private static String password = "test123@";
    private static Integer num = 0;


    private static String token = "";//登录令牌
    private Timer timer = new Timer();//保活定时器

    @Autowired
    private OkHttpClients okHttpClients;

    @Autowired
    private HillstoneProperties hillstoneProperties;

    /**
     * 登录
     */
    @Override
    public String login() {
        if (StrUtils.isNotNull(this.token)){
            this.num ++;
            return this.token;
        }
        try {
            String baseurl = hillstoneProperties.getBaseurl();
            String username = hillstoneProperties.getUsername();
            String signature = EncryptUtils.md5(hillstoneProperties.getPassword());

            String loginurl = HillstoneRequestTypeEnum.LOGION_V1.getUrl();
            if (hillstoneProperties.getVersion().equals(2)){
                loginurl = HillstoneRequestTypeEnum.LOGION_V2.getUrl();
            }

            //第一次登录
            LoginDto loginDto = new LoginDto();
            loginDto.setUserName(username);
            loginDto.setClientType(hillstoneProperties.getClientType());
            loginDto.setIpAddress("");

            String result = okHttpClients.post(baseurl + loginurl , JSON.toJSONString(loginDto), null, hillstoneProperties.getUseSSL(), 401);
            if (StrUtils.isNotNull(result)){
                JSONObject resultObj = JSON.parseObject(result);
                String randomKey = resultObj.getString("randomKey");
                String realm = resultObj.getString("realm");
                String encryptType = resultObj.getString("encryptType");
                String method = resultObj.getString("method");

                if(encryptType.equals("MD5")) {
                    signature = EncryptUtils.md5(username + signature);
                    signature = EncryptUtils.md5(signature);
                    signature = EncryptUtils.md5(username + ":" + realm + ":" + signature);
                    signature = EncryptUtils.md5(signature + ":" + randomKey);
                    loginDto.setSignature(signature);
                }
                loginDto.setRandomKey(randomKey);
                loginDto.setEncryptType(encryptType);
                String result1 = okHttpClients.post(baseurl + loginurl , JSON.toJSONString(loginDto), null, hillstoneProperties.getUseSSL(), 401);
                if (StrUtils.isNotNull(result1)){
                    JSONObject resultObj2 = JSON.parseObject(result1);
                    Integer duration = resultObj2.getInteger("duration");//有效时长
                    String token = resultObj2.getString("token");//登录令牌
                    this.token = token;
                    this.num ++;
                    logger.info("登录成功：" + token);

                    //令牌保活
                    this.timer = new Timer();
                    TimerTask task = new TimerTask() {
                        @Override
                        public void run() {
                            keepalive();
                        }
                    };
//                    this.timer.schedule(task, 3000, (duration - 20) * 1000);

                    this.timer.schedule(task, (duration - 20) * 1000, (duration - 20) * 1000);
                }
            }
        }catch (Exception e){
            destoryToken();
            logger.error(e.getMessage(),e);
        }
        return this.token;
    }

    /**
     * 令牌保活
     */
    public void keepalive(){
        Map<String,String> paramMap = new HashMap<>();
        paramMap.put("token", this.token);

        Map<String,String> headerMap = new HashMap<>();
        headerMap.put("X-Subject-Token", this.token);

        String url = HillstoneRequestTypeEnum.KEEPALIVE_V1.getUrl();
        if (hillstoneProperties.getVersion().equals(2)){
            url = HillstoneRequestTypeEnum.KEEPALIVE_V2.getUrl();
        }

        String result = okHttpClients.put(hillstoneProperties.getBaseurl() + url, paramMap, headerMap, hillstoneProperties.getUseSSL());
        if (StrUtils.isNotNull(result) && !result.equals("error")) {
            JSONObject resultObj = JSON.parseObject(result);
            Integer code = resultObj.getInteger("code");
            if (code.equals(hillstoneProperties.getTokenSuccessCode())){
                logger.info("系统保活成功");
            }else{
                clearToken();
                login();
                logger.error("系统保活失败");
            }
        } else {
            clearToken();
            logger.error("系统保活失败");
        }
    }

    /**
     * 销毁会话
     */
    @Override
    public void destoryToken(){
        if (this.num == 0){
            return ;
        }
        this.num --;
        if (num > 0){
            return ;
        }
        Map<String,String> paramMap = new HashMap<>();
        paramMap.put("token", this.token);

        Map<String,String> headerMap = new HashMap<>();
        headerMap.put("X-Subject-Token", this.token);

        String url = HillstoneRequestTypeEnum.DESTORY_V1.getUrl();
        if (hillstoneProperties.getVersion().equals(2)){
            url = HillstoneRequestTypeEnum.DESTORY_V2.getUrl();
        }
        String result = okHttpClients.post(hillstoneProperties.getBaseurl() + url, paramMap, headerMap, hillstoneProperties.getUseSSL());
        if (StrUtils.isNotNull(result) && !result.equals("error")) {
            JSONObject resultObj = JSON.parseObject(result);
            Integer code = resultObj.getInteger("code");
            if (code.equals(hillstoneProperties.getTokenSuccessCode())){
                clearToken();
                logger.info("会话销毁成功");
            }
        }
    }

    /**
     * 清空令牌和定时任务
     */
    public void clearToken(){
        this.token = "";//登录令牌置空
        this.timer.cancel();//终止定时器
        this.num = 0;//登录数量
    }

    public String getHillstone(String url){
        Map<String,String> headerMap = new HashMap<>();
        headerMap.put("X-Subject-Token", this.token);

        String result = okHttpClients.get(hillstoneProperties.getBaseurl() + url, headerMap, hillstoneProperties.getUseSSL());
        if (StrUtils.isNotNull(result) && !result.equals("error")) {
            return result;
        }
        return null;
    }

    /**
     * POST请求json数据
     * @param url        大华接口请求路径
     * @param jsonBody   请求内容参数
     * @return
     */
    @Override
    public String postHillstoneJson(String url,String jsonBody) {
        Map<String,String> headerMap = new HashMap<>();
        headerMap.put("X-Subject-Token", this.token);

        String result = okHttpClients.post(hillstoneProperties.getBaseurl() + url,jsonBody, headerMap, hillstoneProperties.getUseSSL());
        if (StrUtils.isNotNull(result) && !result.equals("error")) {
            return result;
        }
        return null;
    }
}
